package com.gitee.faster.webdav.kernel;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.core.text.AntPathMatcher;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.text.StrPool;
import com.gitee.faster.webdav.common.constant.Constants;
import com.gitee.faster.webdav.common.helper.JsonHelper;
import com.gitee.faster.webdav.logger.LoggerLevel;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.File;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author hongda.li
 */
@Data
@Accessors(chain = true)
public final class Configuration {
    /**
     * 单例实例
     */
    private static final Configuration CONFIGURATION = new Configuration();

    /**
     * 日志名称匹配器
     */
    private final transient AntPathMatcher loggerMatcher = new AntPathMatcher(StrPool.DOT);

    /**
     * 日志级别缓存
     */
    private final transient Map<String, LoggerLevel> loggerLevelMap = new ConcurrentHashMap<>(2 << 5);

    /**
     * 默认日志级别
     */
    private LoggerLevel defaultLevel = LoggerLevel.DEBUG;

    /**
     * 日志存储路径
     */
    private String loggerPath = Constants.LOG_PATH;

    /**
     * 挂载路径
     */
    private String mountPath = StrPool.SLASH;

    /**
     * WebDav 文件存储路径
     * 路径后缀不包含 /
     */
    private String storagePath = FileUtil.getUserHomePath();

    /**
     * 写入缓冲区默认大小 4KB
     */
    private int writeBufferSize = 1024 * 8;

    /**
     * 读取缓冲区默认大小 4KB
     */
    private int readBufferSize = 1024 * 8;

    /**
     * 主机地址
     */
    private String host = NetUtil.getLocalhostStr();

    /**
     * 端口号
     */
    private int port = 12345;

    /**
     * 最大检索深度
     */
    private int maxDepth = 3;

    /**
     * 账号
     */
    private String username;

    /**
     * 密码
     */
    private String password;

    public synchronized void rewriteToJson() {
        new FileWriter(new File(Constants.Config.CONFIG_JSON_NAME)).write(JsonHelper.toJson(this));
    }

    public synchronized void rewriteFromJson() {
        File config = new File(Constants.Config.CONFIG_JSON_NAME);
        if (!FileUtil.exist(config)) {
            return;
        }

        String jsonStr = new FileReader(config).readString();
        if (CharSequenceUtil.isBlank(jsonStr)) {
            return;
        }

        this.from(JsonHelper.fromJson(jsonStr, Configuration.class));
    }

    public void from(Configuration other) {
        if (other == null) {
            return;
        }
        this.host = other.host;
        this.port = other.port;
        this.username = other.username;
        this.password = other.password;
        this.mountPath = other.mountPath;
        this.loggerPath = other.loggerPath;
        this.storagePath = other.storagePath;
        this.defaultLevel = other.defaultLevel;
        this.readBufferSize = other.readBufferSize;
        this.writeBufferSize = other.writeBufferSize;
    }

    /**
     * 获取全局唯一实例
     *
     * @return 单例模式
     */
    public static Configuration getInstance() {
        return CONFIGURATION;
    }

    /**
     * 将主机地址和端口号转为标准 HTTP 地址
     *
     * @return HTTP 地址
     */
    public UrlBuilder httpPathBuilder() {
        return UrlBuilder.ofHttp(this.host).setPort(this.port);
    }
}
